package com.mzy.xmyx.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mzy.xmyx.acl.mapper.PermissionMapper;
import com.mzy.xmyx.acl.service.PermissionService;
import com.mzy.xmyx.acl.service.RolePermissionService;
import com.mzy.xmyx.model.acl.Permission;
import com.mzy.xmyx.model.acl.RolePermission;
import com.mzy.xmyx.acl.util.PermissionHelper;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Override
    public List<Permission> queryAllPermission() {
        // 1. 查询所有菜单
        List<Permission> permissionAllList = permissionMapper.selectList(null);

        // 2. 组合树形结构
        List<Permission> trees = PermissionHelper.build(permissionAllList);
        return trees;
    }


    @Override
    public Boolean removeChildById(Long id) {
        // 1. 创建list集合idList，封装所有要删除的菜单
        List<Long> permissionIdList = new ArrayList<>();
        long start = System.currentTimeMillis();

        this.getAllPermissionId(id, permissionIdList);
        long end = System.currentTimeMillis();
        log.info(end - start + "");
        int row = permissionMapper.deleteBatchIds(permissionIdList);
        return row > 0;
    }

    private void getAllPermissionId(Long id, List<Long> permissionIdList) {
        // 先添加最顶级菜单id
        permissionIdList.add(id);

        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Permission::getPid, id);
        List<Permission> childPermissionList = permissionMapper.selectList(queryWrapper);

        childPermissionList.forEach(permission -> {
            // 优化前 120ms左右
            // permissionIdList.add(permission.getId());
            // getAllPermissionId(permission.getId(), permissionIdList);

            // 判断当前菜单是否有子菜单 优化后 60ms左右
            if (permission.getType() > 1) {
                // 没有子菜单 添加
                permissionIdList.add(permission.getId());
            } else {
                // 有子菜单 继续遍历
                getAllPermissionId(permission.getId(), permissionIdList);
            }

        });
    }


    @Override
    public List<Permission> getPermissionByRoleId(Long roleId) {
        // 查询所有的权限
        List<Permission> allPermissions = permissionMapper.selectList(null);

        // 查询当前 roleId 的所有权限
        LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePermission::getRoleId, roleId);
        List<RolePermission> rolePermissionList = rolePermissionService.list(queryWrapper);
        // 获取已分配的所有权限id
        List<Long> assignedPermissionIdList = rolePermissionList.stream()
                .map(rolePermission -> rolePermission.getPermissionId())
                .collect(Collectors.toList());

        // 将已分配权限的isSelect标记为true
        allPermissions.forEach(permission -> {
            if (assignedPermissionIdList.contains(permission.getId())) {
                permission.setSelect(true);
            }
        });
        // 转换树形结构
        List<Permission> trees = PermissionHelper.build(allPermissions);
        return trees;
    }

    @Override
    public Boolean saveRolePermissionRelationship(Long roleId, List<Long> permissionIdList) {

        // 1. 删除之前的角色权限关系
        // 1.1 获取之前的角色关系关系
        val queryWrapper = new LambdaQueryWrapper<RolePermission>();
        queryWrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(queryWrapper);
        // 2. 添加新的角色权限关系
        // 2.1 构建角色权限关系集合
        List<RolePermission> rolePermissionList = permissionIdList.stream()
                .map(permissionId -> new RolePermission(roleId, permissionId))
                .collect(Collectors.toList());
        boolean isSuccess = rolePermissionService.saveBatch(rolePermissionList);
        return isSuccess;
    }


}
